package com.yu.crm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whyxzz.arcface.ArcFace;
import com.yu.crm.domain.pojo.*;
import com.yu.crm.mapper.CrmUserMapper;
import com.yu.crm.service.CrmDepartmentMemberService;
import com.yu.crm.service.CrmMenuService;
import com.yu.crm.service.CrmRoleService;
import com.yu.crm.service.CrmUserService;
import com.yu.crm.utils.EigenValue;
import com.yu.crm.ws.WebSocketClient;
import com.yxzz.common.config.UserCacheManager;
import com.yxzz.common.domain.entity.TokenUser;
import com.yxzz.common.exception.GeneralException;
import com.yxzz.common.helper.*;
import com.yxzz.common.helper.valid.ValidatorHelpers;
import com.yxzz.common.utils.MD5Utils;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author donnie-bin
 * @since 2019-06-10
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CrmUserServiceImpl extends ServiceImpl<CrmUserMapper, CrmUser> implements CrmUserService {
    @Autowired
    CrmDepartmentMemberService crmDepartmentMemberService;
    @Autowired
    UserCacheManager userCacheManager;
    @Autowired
    CrmMenuService crmMenuService;
    @Autowired
    WebSocketClient webSocketClient;
    @Autowired
    CrmEigenvalueService crmEigenvalueService;
    @Autowired
    CrmRoleService roleService;

    @Override
    public boolean saveOrUpdate(CrmUser entity) {
        if(DataHelpers.isEmpty(entity.getId())){
            LambdaQueryWrapper<CrmUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(CrmUser::getUserId, entity.getUserId());
            int oldCount = super.count(lambdaQueryWrapper);
            ValidatorHelpers.validateDataExist("用户ID不能重复", oldCount);
            entity.setGmtCreate(DateHelpers.now());
            entity.setGmtModified(DateHelpers.now());
            return ExceptionHelpers.checkData(super.save(entity), "保存成功");
        }else{
            entity.setGmtModified(DateHelpers.now());
            return ExceptionHelpers.checkData(super.updateById(entity), "更新失败");
        }
    }

    @Override
    public boolean removeById(Serializable id) {
        CrmUser crmUser = baseMapper.selectById(id);
        if(DataHelpers.isNotEmpty(crmUser)){
            QueryWrapper<CrmDepartmentMember> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("user_id",crmUser.getUserId());
            queryWrapper.eq("is_deleted",0);
            crmDepartmentMemberService.remove(queryWrapper);

            return super.removeById(id);
        }else{
            return false;
        }
    }

    @Override
    public CrmUser getById(Serializable id) {
        CrmUser byId = super.getById(id);
        if(DataHelpers.isNotEmpty(byId)){
            List<HashMap<String, Object>> menusByUserId = crmMenuService.getMenusByUserId(null);
            if(DataHelpers.isNotEmpty(menusByUserId)){
                byId.setRoles(menusByUserId);
            }
            return byId;
        }else{
            throw  new GeneralException("此用户不存在");
        }
    }

    @Override
    public CrmUser infoByUserId() {
        String userId = userCacheManager.getCurrentUser().getUserId();
//        String userId = "admin";
        QueryWrapper<CrmUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("is_deleted",0);
        CrmUser crmUser = baseMapper.selectOne(queryWrapper);
        if (DataHelpers.isEmpty(crmUser)) {
            throw new GeneralException("该用户不存在");
        }
        List<CrmRole> roleList = roleService.getListByUserId();
        crmUser.setRoleList(roleList);
        /*if (DataHelpers.isNotEmpty(roleList)) {
            present = roleList.stream().filter(m -> m.getRoleName().contains("承办")).findAny().isPresent();
        }
        if(DataHelpers.isNotEmpty(crmUser)){
            List<HashMap<String, Object>> menusByUserId = crmMenuService.getMenusByUserId(null);
            if(DataHelpers.isNotEmpty(menusByUserId)){
                crmUser.setRoles(menusByUserId);
                if (DataHelpers.isNotEmpty(roleList) && present) {
                    //承办人
                    Iterator<HashMap<String, Object>> iterator = menusByUserId.iterator();
                    while (iterator.hasNext()) {
                        HashMap<String, Object> map = iterator.next();
                        Long id = (Long) map.get("id");
                        if (id.toString().equals("2")) {
                            menusByUserId.remove(map);
                            return crmUser;
                        }
                    }
                }
            }
            return crmUser;
        }else{
            throw new GeneralException("此用户不存在");
        }*/
        return crmUser;
    }

    @Override
    public IPage<CrmUser> list(IPage<CrmUser> page, CrmUser queryInfo) {
        LambdaQueryWrapper<CrmUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(DataHelpers.isNotEmpty(queryInfo.getUserId())){
            lambdaQueryWrapper.like(CrmUser::getUserId, queryInfo.getUserId());
        }
        if(DataHelpers.isNotEmpty(queryInfo.getUserName())){
            lambdaQueryWrapper.like(CrmUser::getUserName, queryInfo.getUserName());
        }
        lambdaQueryWrapper.orderByAsc(CrmUser::getUserName);
        return super.page(page, lambdaQueryWrapper);
    }

    /**
     * 修改用户密码
     * @param entity
     * @return
     */
    @Override
    public Boolean updatePwd(CrmUser entity) {
        if (entity.getLoginType() == 2) {
            if(DataHelpers.isNotEmpty(entity.getLoginExtraCode())){
                Boolean aBoolean = RedisHelpers.hasKey("AliCode:" + entity.getUserAccountId());
                if (aBoolean) {
                    //获取redis对应code
                    String redisCode = RedisHelpers.get("AliCode:" + entity.getUserAccountId()).toString();
                    if (redisCode.equals(entity.getLoginExtraCode())) {
                        QueryWrapper<CrmUser> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("user_account_id", entity.getUserAccountId());
                        queryWrapper.eq("is_deleted", 0);

                        CrmUser crmUser = baseMapper.selectOne(queryWrapper);
                        crmUser.setUserAccountPwd(MD5Utils.MD5Encode(entity.getNewUserAccountPwd()));
                        crmUser.setGmtModified(LocalDateTime.now());
                        ValidatorHelpers.validateDataSave(baseMapper.updateById(crmUser));
                        return true;
                    }
                } else {
                    throw new GeneralException("验证码已失效,请重新获取");
                }
            }
        } else if (entity.getLoginType() == 1) {
            if(DataHelpers.isNotEmpty(entity.getUserAccountPwd())){
                QueryWrapper<CrmUser> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("user_account_id", entity.getUserAccountId());
                queryWrapper.eq("user_account_pwd", MD5Utils.MD5Encode(entity.getUserAccountPwd()));
                queryWrapper.eq("is_deleted", 0);
                CrmUser crmUser = baseMapper.selectOne(queryWrapper);
                if (DataHelpers.isNotEmpty(crmUser)) {
                    crmUser.setUserAccountPwd(MD5Utils.MD5Encode(entity.getNewUserAccountPwd()));
                    crmUser.setGmtModified(LocalDateTime.now());
                    ValidatorHelpers.validateDataSave(baseMapper.updateById(crmUser));
                    return true;
                } else {
                    throw new GeneralException("账户或密码错误");
                }
            }
        }
        return false;
    }

    @Override
    public void updateByUserId(CrmUser crmUser) {
        CrmUser byUserId = getByUserId(crmUser.getUserId());
        try{
        Boolean flag=false;
            if(DataHelpers.isNotEmpty(byUserId)){
                String userId= userCacheManager.getCurrentUser().getUserId();
                byUserId.setUserId(userId);
                byUserId.setGmtModified(LocalDateTime.now());
                byUserId.setUserFaceUrl(crmUser.getUserFaceUrl());
                if(DataHelpers.isNotEmpty(crmUser.getUserFaceUrl())){
                    byte[] bytes = EigenValue.extractFeature(crmUser.getUserFaceUrl());
                    if(DataHelpers.isNotEmpty(bytes)){
                        byUserId.setCertificateEigen(bytes);
                        flag=true;
                    }

                    ValidatorHelpers.validateDataSave(baseMapper.updateById(byUserId));
                }

                if(flag){
                    //CrmUser crmUser1 = baseMapper.selectById(crmUser.getUserId());
                    //特征值第一次入库
                    CrmEigenvalue crmEigenvalue = new CrmEigenvalue();
                    crmEigenvalue.setType(2);
                    crmEigenvalue.setCertificateEigen(byUserId.getCertificateEigen());
                    crmEigenvalue.setCertificateBase(byUserId.getUserFaceUrl());
                    crmEigenvalue.setUserId(userId);
                    crmEigenvalue.setGender(byUserId.getUserSex());
                    crmEigenvalue.setCameraFeature(byUserId.getUserFaceUrl());
                    crmEigenvalueService.add(crmEigenvalue);

                    String cameraFeature = Base64.encodeBase64String(byUserId.getCertificateEigen());
                    webSocketClient.sendMessageCameraFeature(cameraFeature,"",byUserId.getUserId(),byUserId.getUserName(),2);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new GeneralException("操作失败");
        }
    }

    @Override
    public CrmUser getByUserId(String userId) {
        List<CrmUser> userList = baseMapper.getUser(userId);
        if (DataHelpers.isNotEmpty(userList) && userList.size() > 0) {
            return userList.get(userList.size()-1);
        }else {
            throw new GeneralException("该用户不存在");
        }

    }

    @Override
    public String isUser(byte[] bytes, ArcFace arcFace) {
        QueryWrapper<CrmUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted",0);
        List<CrmUser> crmUsers = baseMapper.selectList(queryWrapper);
        if (DataHelpers.isNotEmpty(crmUsers)) {
            for (CrmUser crmUser:crmUsers
            ) {
                if (arcFace.compareFaceFeature(bytes, crmUser.getCertificateEigen())) {
                    return crmUser.getUserId();
                }
            }
        }
        return "";
    }

    @Override
    /**
     * 通过用户名和密码登录
     * #@param phone 用户名
     * # @param pwd 密码
     * # @param type 不传 接待员登录 ，传1是访客后台登录
     * @param map1
     */
    public  Map<String, Object> login(HashMap<String,Object>  map1) {
        try {
            String phone=map1.get("username").toString();
            String pwd=map1.get("pwd").toString();
            Map<String, Object> map=new HashMap<>();
            //通过手机号(登录名)和密码(未加密)登录
            CrmUser crmUser =infoByPhoneAndPassword(phone, pwd);
            if(DataHelpers.isNotEmpty(crmUser)){
                //通过用户表主键搜索员工信息
                    String token = TokenHelpers.generateTokenString(crmUser.getUserId());
                    //设置redis缓存
                    TokenUser tokenUser = new TokenUser();
                    tokenUser.setToken(token);
                    tokenUser.setUserId(crmUser.getUserId());
                    userCacheManager.save(token, tokenUser, 3600 * 24);
                    map.put("token",token);
            }else{
                throw new GeneralException("用户名或密码错误");
            }
            return map;
        }catch (Exception e){
            e.printStackTrace();
            throw new GeneralException("操作失败");
        }
    }

    @Override
    public boolean isByUserId(String userId) {
        QueryWrapper<CrmUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("is_deleted",0);
        List<CrmUser> crmUsers = baseMapper.selectList(queryWrapper);
        if (DataHelpers.isNotEmpty(crmUsers) || crmUsers.size()>0) {
            return true;
        }else {
            return false;
        }
    }

    /**
     * 通过手机号(登录名)和密码(未加密)登录
     * @param phone 手机号
     * @param password 密码
     * @return
     */
    public CrmUser infoByPhoneAndPassword(String phone, String password){
        try {
            //加密密码
            password= MD5Utils.MD5Encode(password);
            QueryWrapper<CrmUser> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("user_account_id",phone);
            queryWrapper.eq("user_account_pwd",password);
            queryWrapper.eq("is_deleted",0);
            return baseMapper.selectOne(queryWrapper);
        }catch (Exception e){
            e.printStackTrace();
            throw new GeneralException("操作失败");
        }
    }

}
